package com.example.springboot.service.impl;

import com.example.springboot.entity.PestImage;
import com.example.springboot.exception.FileDeleteException;
import com.example.springboot.mapper.PestImageMapper;
import com.example.springboot.service.IPestImageService;
import com.example.springboot.utils.FileUtil;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class PestImageService implements IPestImageService {

    @Autowired
    private PestImageMapper pestImageMapper;

    @Autowired
    private MinioClient minioClient;
    
    @Autowired
    private FileUtil fileUtil;

    @Value("${minio.bucketName}")
    private String bucketName;


    /**
     * 批量保存图片并更新数据库
     *
     * @param imageNames 图片列表
     */
    @Override
    public void saveImages(Integer pestId ,List<String> imageNames) {

        List<PestImage> pestImages = new ArrayList<>();
        for (String imageName : imageNames) {
            PestImage pestImage = new PestImage();
            pestImage.setPestId(pestId);
            pestImage.setBucketName(bucketName);
            pestImage.setImageName(imageName);
            pestImage.setCreatedTime(LocalDateTime.now());
            pestImages.add(pestImage);
        }
        pestImageMapper.saveImages(pestImages);

    }

    /**
     * 根据图片id获取单个图片url
     *
     * @param id id
     * @return 图片url
     */
    @Override
    public String getUrlById(Integer id) {
        PestImage pestImage = pestImageMapper.getImageById(id);
        String imageName = pestImage.getImageName();
        String imageUrl;
        try {
            imageUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .bucket(bucketName)
                    .object(imageName)
                    .build()
            );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return imageUrl;
    }

    /**
     * 根据虫害id获取图片url列表
     *
     * @param pestId id
     * @return 图片列表
     */
    @Override
    public List<String> getByPestId(Integer pestId) {
        List<PestImage> pestImages = pestImageMapper.findByPestId(pestId);
        List<String> imageUrls = new ArrayList<>();
        for (PestImage pestImage : pestImages){
            String imageName = pestImage.getImageName();
            String imageUrl;
            try {
                imageUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(imageName)
                        .expiry(24, TimeUnit.HOURS)
                        .build()
                );
                imageUrls.add(imageUrl);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return imageUrls;
    }

    /**
     * 删除单个图片并更新数据库,(删除数据库url以及minio对应存储图片)
     *
     * @param id id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)// 添加事务管理
    public void deleteImage(Integer id) {
        PestImage pestImage = pestImageMapper.getImageById(id);
        if (pestImage != null) {
            try {
                String imageName = pestImage.getImageName();
                minioClient.removeObject( RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(imageName)
                        .build()
                );
                pestImageMapper.deleteById(id);
            } catch (Exception e) {
                log.error("删除图片失败", e);
                throw new FileDeleteException("图片删除错误", e);
            }
        }
    }

    /**
     * 批量删除图片并更新数据库(删除数据库url以及minio对应存储图片)
     *目前没在使用
     * @param pestId id
     */
    @Override
    @Transactional
    public void deleteByPestId(Integer pestId) {
        List<PestImage> pestImages = pestImageMapper.findByPestId(pestId);

        for (PestImage pestImage : pestImages) {
            try {

                String imageName = pestImage.getImageName();
                log.info("删除 MinIO 文件：{}", imageName);

                // 调用 MinIO 删除接口
                minioClient.removeObject(
                        RemoveObjectArgs.builder()
                                .bucket(bucketName)
                                .object(imageName)
                                .build()
                );
            } catch (Exception e) {
                throw new FileDeleteException("图片删除错误", e);
            }
        }
        log.info("删除 MinIO 文件成功");
        log.info("bucketName：{} ", bucketName);
        pestImageMapper.deleteByPestId(pestId);
        log.info("删除数据库文件成功");
    }
    
    /**
     * 更新虫害的图片（先删除原图片，再添加新图片）
     *
     * @param pestId 虫害ID
     * @param files  新图片文件列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateImages(Integer pestId, MultipartFile[] files) {
        // 先删除原有图片
        deleteByPestId(pestId);
        
        // 上传新图片
        List<String> imageNames = new ArrayList<>();
        for (MultipartFile file : files) {
            try {
                fileUtil.upload(file);
                imageNames.add(file.getOriginalFilename());
            } catch (Exception e) {
                log.error("上传文件 [{}] 失败", file.getOriginalFilename(), e);
                throw new RuntimeException("图片上传失败", e);
            }
        }
        
        // 保存新图片信息到数据库
        saveImages(pestId, imageNames);
    }
}